<template>
  <n-card>
    <template #header>
      <div class="wireless-card-title">
        <span>无线模块</span>
        <n-tag class="title-tag" type="info" size="small" round>{{ formValue.firmware }}</n-tag>
      </div>
    </template>
    <n-grid :cols="7">
      <n-gi :span="3">
        <n-card :bordered="false">
          <div style="height: 710px">
            <n-form
              ref="formRef"
              :rules="rules"
              :label-width="150"
              :model="formValue"
              label-placement="left"
            >
              <n-form-item path="pwd" label="配对秘钥"
                ><n-input v-model:value="formValue.pwd"
              /></n-form-item>
              <n-form-item path="lcaddress" label="无线模块地址"
                ><n-input v-model:value="formValue.lcaddress"
              /></n-form-item>
              <n-form-item path="rsnode" label="无线模块工作模式">
                <n-radio-group v-model:value="formValue.rsnode" name="rsnodegroup">
                  <n-space>
                    <n-radio v-for="rsnode in rsnodes" :key="rsnode.value" :value="rsnode.value">
                      {{ rsnode.label }}
                    </n-radio>
                  </n-space>
                </n-radio-group>
              </n-form-item>
              <n-form-item required label="无线模块频段">
                <n-checkbox-group v-model:value="lcghzsValue">
                  <n-space item-style="display: flex;">
                    <n-checkbox v-for="lcghz in lcghzs" :key="lcghz.value" :value="lcghz.value">
                      {{ lcghz.label }}
                    </n-checkbox>
                  </n-space>
                </n-checkbox-group>
              </n-form-item>
              <n-form-item path="lcdbm" label="无线模块发射功率">
                <n-select v-model:value="formValue.lcdbm" :options="powerOptions" />
              </n-form-item>
              <n-form-item v-if="formValue.rsnode === '1'" path="updown" label="上下行分配">
                <n-radio-group v-model:value="formValue.updown" name="updowngroup">
                  <n-space>
                    <n-radio v-for="updown in updowns" :key="updown.value" :value="updown.value">
                      {{ updown.label }}
                    </n-radio>
                  </n-space>
                </n-radio-group>
              </n-form-item>
              <n-form-item v-if="formValue.rsnode === '1'" path="bandwidth" label="传输带宽">
                <n-select v-model:value="formValue.bandwidth" :options="bandwidthOptions" />
              </n-form-item>
              <n-form-item label="">
                <n-space>
                  <n-popconfirm
                    @positive-click="submitConfighandler"
                    @negative-click="submitConfighandlerNegative"
                  >
                    <template #trigger>
                      <n-button type="primary" style="margin-left: 150px">提交配置</n-button>
                    </template>
                    提交配置会导致系统重新启动，请确认是否提交。
                  </n-popconfirm>
                  <n-popconfirm @positive-click="restartHandler">
                    <template #trigger>
                      <n-button>重启设备</n-button>
                    </template>
                    系统会重启，请确认是否重启
                  </n-popconfirm>
                </n-space>
              </n-form-item>
            </n-form>
          </div>
        </n-card>
      </n-gi>
      <n-gi :span="4">
        <n-card :bordered="false">
          <div>
            <n-data-table
              v-if="formValue.rsnode === '1'"
              :columns="centerColumns"
              :data="centerData"
              :row-class-name="rowClassName"
            />
            <n-data-table
              v-else-if="formValue.rsnode === '2'"
              :columns="senderColumns"
              :data="senderData"
              :row-class-name="rowClassName"
            />
            <br />
            <n-space>
              <n-button @click="openLogHandler">打开调试信息</n-button>
              <n-button @click="closeLogHandler">关闭调试信息</n-button>
              <n-button @click="clearLogHandler">清除</n-button>
            </n-space>
            <br />
            <n-log ref="logInstRef" :log="logContent" trim style="height: 450px" />
          </div>
        </n-card>
      </n-gi>
    </n-grid>
  </n-card>
</template>
<script lang="ts" setup>
  import type { DataTableBaseColumn, LogInst } from 'naive-ui';
  import type { FormInst, FormItemInst, FormItemRule, FormRules } from 'naive-ui';
  import { NGradientText, NTag, useMessage } from 'naive-ui';
  import { getWireless, setWireless, getlog, restart, getSenderLog } from '@/api/wireless';
  import type { LogMessage, Sender } from '@/api/wireless';
  import {
    onMounted,
    onUnmounted,
    reactive,
    ref,
    watch,
    watchEffect,
    nextTick,
    computed,
    h,
  } from 'vue';
  import type { Wireless } from '@/api/wireless';
  import { RowData } from 'naive-ui/lib/data-table/src/interface';

  const message = useMessage();

  // 工作模式(中心 发射)
  const rsnodes = [
    {
      value: '1',
      label: '中心节点',
    },
    {
      value: '2',
      label: '发射节点',
    },
  ];

  // 频段
  const lcghzs = [
    {
      value: '01',
      label: '800M',
    },
    {
      value: '04',
      label: '1.4GHz',
    },
    {
      value: '08',
      label: '2.4GHz',
    },
  ];

  const lcghzMap = new Map([
    ['0d', ['01', '04', '08']],
    ['0c', ['04', '08']],
    ['09', ['01', '08']],
    ['05', ['01', '04']],
    ['08', ['08']],
    ['04', ['04']],
    ['01', ['01']],
  ]);

  const lcghzsValue = ref<null | string[]>(null);
  function parseLcghz(lcghz: string) {
    lcghzsValue.value = lcghzMap.get(lcghz) ?? null;
  }

  // 发射功率
  const basePowerArr = [-40, -30, -20, -10, -5].concat(Array.from({ length: 26 }, (_, i) => i));
  const powerOptions = basePowerArr.map((value, _) => ({
    value: value.toString(),
    label: value.toString(),
  }));

  // 上下行分配
  const updowns = [
    {
      value: '3',
      label: '1Down4Up',
    },
    {
      value: '0',
      label: '2Down3Up',
    },
    {
      value: '1',
      label: '3Down2Up',
    },
    {
      value: '2',
      label: '4Down1Up',
    },
  ];

  // 带宽
  const bandwidthOptions = [
    {
      value: '0',
      label: '1.4M',
    },
    {
      value: '1',
      label: '3M',
    },
    {
      value: '2',
      label: '5M',
    },
    {
      value: '3',
      label: '10M',
    },
    {
      value: '5',
      label: '20M',
    },
  ];

  const formValue = reactive<Wireless>({
    bandwidth: '',
    firmware: '',
    frqLck: '',
    lcaddress: '',
    lcdbm: '',
    lcghz: '',
    pass: '',
    pwd: '',
    rsnode: '',
    updown: '',
    user: '',
  });

  const formRef = ref<FormInst | null>(null);
  const rules: FormRules = {
    bandwidth: [{ required: true }],
    lcaddress: [
      {
        required: true,
        validator(rule: FormItemRule, value: string) {
          const ipRegex =
            /^(\d{1,2}|1\d\d|2[0-4]\d|25[0-5])\.(\d{1,2}|1\d\d|2[0-4]\d|25[0-5])\.(\d{1,2}|1\d\d|2[0-4]\d|25[0-5])\.(\d{1,2}|1\d\d|2[0-4]\d|25[0-5])$/;
          if (!value) {
            return new Error('ip地址不能为空');
          }
          if (!ipRegex.test(value)) {
            return new Error('ip地址不合法');
          }
          return true;
        },
        trigger: ['input', 'blur'],
      },
    ],
    lcdbm: [
      {
        required: true,
      },
    ],
    lcghz: [
      {
        required: true,
        validator(rule: FormItemRule, value: string) {
          console.log(value);
          return true;
        },
        trigger: ['input', 'blur'],
      },
    ],
    pwd: [
      {
        required: true,
        validator(rule: FormItemRule, value: string) {
          const pwdRegex = /(^[a-f1-9]{1}[a-f0-9]{0,63}$)/;
          if (!value) {
            return new Error('配对秘钥不能为空');
          }
          if (!pwdRegex.test(value)) {
            return new Error('配对密钥是不超过64个的HEX字串，不以0开头');
          }
          if (value.length % 2 !== 0) {
            return new Error('配对密钥必须是偶数个');
          }
          return true;
        },
        trigger: ['input', 'blur'],
      },
    ],
    rsnode: [{ required: true }],
    updown: [{ required: true }],
  };

  async function restartHandler() {
    await restart();
  }

  function submitConfighandlerNegative() {
    console.log('取消提交');
  }

  function submitConfighandler(e: MouseEvent) {
    e.preventDefault();
    formRef.value?.validate(async (errors) => {
      if (!errors) {
        //message.success('验证成功');
        //console.log(lcghzsValue.value);
        if (lcghzsValue.value === null || lcghzsValue.value?.length === 0) {
          message.error('频段选择不能为空');
          return;
        }
        let lcghzNum = 0;
        for (let i = 0; i < lcghzsValue.value?.length; ++i) {
          lcghzNum += parseInt(lcghzsValue.value[i], 16);
          //console.log(lcghzNum.toString(16).padStart(2, '0').toLowerCase());
        }
        formValue.lcghz = lcghzNum.toString(16).padStart(2, '0').toLowerCase();
        //console.log(objectToConfigString(formValue));
        const result = await setWireless(objectToConfigString(formValue));
      } else {
        console.log(errors);
        message.error('验证失败');
      }
    });
  }

  function objectToConfigString(configObj) {
    // 确保所有值都转换为字符串
    const entries = Object.entries(configObj).map(([key, value]) => {
      return `${key}\`${String(value)}`;
    });

    return entries.join(';');
  }

  // 列表
  const centerColumns = [
    {
      title: '发射节点',
      key: 'ipAddr',
      className: 'customTabbleClass',
    },
    {
      title: '主/从',
      key: 'mastSlav',
      className: 'customTabbleClass',
    },
    {
      title: 'RSSI',
      key: 'rssi',
      className: 'customTabbleClass',
    },
    {
      title: 'RSRP',
      key: 'rsrp',
      className: 'customTabbleClass',
    },
    {
      title: 'RSRQ',
      key: 'rsrq',
      className: 'customTabbleClass',
    },
    {
      title: 'SNR',
      key: 'snr',
      className: 'customTabbleClass',
    },
    {
      title: 'DIST',
      key: 'dist',
      className: 'customTabbleClass',
    },
    {
      title: 'MAX_SNR',
      key: 'snr_max',
      className: 'customTabbleClass',
    },
    {
      title: 'MIN_SNR',
      key: 'snr_min',
      className: 'customTabbleClass',
    },
    {
      title: '信号强度',
      key: 'strength',
      className: 'customTabbleClass',
      render(row) {
        // 根据RSSI值选择不同的图片
        let imageUrl = '';
        let snrPicId = 6;

        if (row.snr >= 24) snrPicId = 0;
        else if (24 > row.snr && row.snr >= 18) snrPicId = 1;
        else if (18 > row.snr && row.snr >= 12) snrPicId = 2;
        else if (12 > row.snr && row.snr >= 6) snrPicId = 3;
        else if (6 > row.snr && row.snr >= 3) snrPicId = 4;
        else if (3 > row.snr && row.snr >= -3) snrPicId = 5;
        else snrPicId = 6;

        imageUrl = `/images/s${snrPicId}.png`;

        return h(
          'div',
          {
            style: {
              display: 'flex',
              alignItems: 'center',
              gap: '8px',
            },
          },
          [
            h('img', {
              src: imageUrl,
              style: {
                width: '60px',
                height: '40px',
              },
              alt: '信号强度',
            }),
            // h(
            //   'span',
            //   {
            //     style: {
            //       fontSize: '12px',
            //       color: '#666',
            //     },
            //   },
            //   `${row.snr}dBm`
            // ),
          ]
        );
      },
    },
  ];

  const logData = ref<Sender[]>([]);
  const centerData = computed(() => {
    return logData.value !== null
      ? logData.value.map((sender) => ({
          ipAddr: sender.ipAddr,
          mastSlav: sender.mastSlav === 0 ? '主' : '从',
          rssi: sender.rssi,
          rsrp: sender.rsrp,
          rsrq: sender.rsrq,
          snr: sender.snr,
          dist: sender.dist,
          snr_max: sender.snr_max,
          snr_min: sender.snr_min,
        }))
      : [];
  });

  const senderColumns = [
    {
      title: '主/从',
      //   title(_column: DataTableBaseColumn<RowData>) {
      //     return h(
      //       NTag,
      //       {
      //         style: {
      //           backgroundColor: '#abbaca',
      //         },
      //       },
      //       { default: () => '主/从' }
      //     );
      //   },
      key: 'mastSlav',
      className: 'customTabbleClass',
    },
    {
      title: 'EARFCN',
      key: 'earfcn',
      className: 'customTabbleClass',
    },
    {
      title: 'RSSI',
      key: 'rssi',
      className: 'customTabbleClass',
    },
    {
      title: 'RSRP',
      key: 'rsrp',
      className: 'customTabbleClass',
    },
    {
      title: 'RSRQ',
      key: 'rsrq',
      className: 'customTabbleClass',
    },
    {
      title: 'SNR',
      key: 'snr',
      className: 'customTabbleClass',
    },
    {
      title: 'DIST',
      key: 'dist',
      className: 'customTabbleClass',
    },
    {
      title: 'TXPOWER',
      key: 'tx_power',
      className: 'customTabbleClass',
    },
    {
      title: 'SER',
      key: 'ser',
      className: 'customTabbleClass',
    },
    {
      title: 'MAX_SNR',
      key: 'snr_max',
      className: 'customTabbleClass',
    },
    {
      title: 'MIN_SNR',
      key: 'snr_min',
      className: 'customTabbleClass',
    },
    {
      title: '信号强度',
      key: 'strength',
      className: 'customTabbleClass',
      render(row) {
        // 根据RSSI值选择不同的图片
        let imageUrl = '';
        let snrPicId = 6;

        if (row.snr >= 24) snrPicId = 0;
        else if (24 > row.snr && row.snr >= 18) snrPicId = 1;
        else if (18 > row.snr && row.snr >= 12) snrPicId = 2;
        else if (12 > row.snr && row.snr >= 6) snrPicId = 3;
        else if (6 > row.snr && row.snr >= 3) snrPicId = 4;
        else if (3 > row.snr && row.snr >= -3) snrPicId = 5;
        else snrPicId = 6;

        imageUrl = `/images/s${snrPicId}.png`;

        return h(
          'div',
          {
            style: {
              display: 'flex',
              alignItems: 'center',
              gap: '8px',
            },
          },
          [
            h('img', {
              src: imageUrl,
              style: {
                width: '60px',
                height: '40px',
              },
              alt: '信号强度',
            }),
            // h(
            //   'span',
            //   {
            //     style: {
            //       fontSize: '12px',
            //       color: '#666',
            //     },
            //   },
            //   `${row.snr}dBm`
            // ),
          ]
        );
      },
    },
  ];

  const logSenderData = ref<Sender[]>([]);
  const senderData = computed(() => {
    return logSenderData.value !== null
      ? logSenderData.value.map((sender) => ({
          earfcn: sender.earfcn,
          mastSlav: sender.mastSlav === 0 ? '主' : '从',
          rssi: sender.rssi,
          rsrp: sender.rsrp,
          rsrq: sender.rsrq,
          snr: sender.snr,
          dist: sender.dist,
          snr_max: sender.snr_max,
          snr_min: sender.snr_min,
          tx_power: sender.tx_power !== undefined ? sender.tx_power - 10 : undefined,
          ser: sender.ser,
        }))
      : [];
  });

  // 调试信息
  let logIntervalId;
  const logInstRef = ref<LogInst | null>(null);
  const logMsgList = ref<string[]>([]);

  const logContent = computed(() => `${logMsgList.value.join('\n')}\n`);

  function formatLogTime(): string {
    const now = new Date();
    // return `${now.getFullYear()}-${String(now.getMonth() + 1).padStart(2, '0')}-${String(
    //   now.getDate()
    // ).padStart(2, '0')} ${String(now.getHours()).padStart(2, '0')}:${String(
    //   now.getMinutes()
    // ).padStart(2, '0')}:${String(now.getSeconds()).padStart(2, '0')}.${String(
    //   now.getMilliseconds()
    // ).padStart(3, '0')}`;
    return `${now.getFullYear()}-${String(now.getMonth() + 1).padStart(2, '0')}-${String(
      now.getDate()
    ).padStart(2, '0')} ${String(now.getHours()).padStart(2, '0')}:${String(
      now.getMinutes()
    ).padStart(2, '0')}:${String(now.getSeconds()).padStart(2, '0')}`;
  }

  function log(logMsg: LogMessage) {
    if (logMsgList.value.length >= 50) {
      logMsgList.value.shift();
    }

    if (logMsg.senders === null || logMsg.senders === undefined) {
      //console.log(formatLogTime());
      logMsgList.value.push(`${formatLogTime()} 无链路信息`);
    } else {
      let mastSlav1 = '';
      let mastSlav2 = '';
      const timeCurrent = formatLogTime();
      for (let i = 0; i < logMsg.senders.length; ++i) {
        const mastSlav = logMsg.senders[i];
        if (formValue.rsnode === '1') {
          if (i === 0) {
            mastSlav1 = `[${timeCurrent}]主 IP:${mastSlav.ipAddr} rssi:${mastSlav.rssi} rsrp:${mastSlav.rsrp} rsrq:${mastSlav.rsrq} SNR:${mastSlav.snr}(MAX:${mastSlav.snr_max} MIN:${mastSlav.snr_min}) 距离:${mastSlav.dist}米 误码率: ${mastSlav.ser}`;
          } else if (i === 1) {
            mastSlav2 = `[${timeCurrent}]从 IP:${mastSlav.ipAddr} rssi:${mastSlav.rssi} rsrp:${mastSlav.rsrp} rsrq:${mastSlav.rsrq} SNR:${mastSlav.snr}(MAX:${mastSlav.snr_max} MIN:${mastSlav.snr_min}) 距离:${mastSlav.dist}米 误码率: ${mastSlav.ser}`;
          }
        } else if (formValue.rsnode === '2') {
          if (i === 0) {
            mastSlav1 = `[${timeCurrent}]主 频率:${mastSlav.earfcn} rssi:${mastSlav.rssi} rsrp:${
              mastSlav.rsrp
            } rsrq:${mastSlav.rsrq} SNR:${mastSlav.snr}(MAX:${mastSlav.snr_max} MIN:${
              mastSlav.snr_min
            }) 距离:${mastSlav.dist}米 发射功率: ${
              mastSlav.tx_power !== undefined ? mastSlav.tx_power - 10 : undefined
            } 误码率: ${mastSlav.ser}`;
          } else if (i === 1) {
            mastSlav2 = `[${timeCurrent}]从 频率:${mastSlav.earfcn} rssi:${mastSlav.rssi} rsrp:${
              mastSlav.rsrp
            } rsrq:${mastSlav.rsrq} SNR:${mastSlav.snr}(MAX:${mastSlav.snr_max} MIN:${
              mastSlav.snr_min
            }) 距离:${mastSlav.dist}米 发射功率: ${
              mastSlav.tx_power !== undefined ? mastSlav.tx_power - 10 : undefined
            } 误码率: ${mastSlav.ser}`;
          }
        }
      }
      const msgs = `${mastSlav1}\n${mastSlav2}\n.\n`;
      logMsgList.value.push(msgs);
    }
  }

  // 日志信息总是滚动到最新
  watch(logContent, () => {
    nextTick(() => {
      logInstRef.value?.scrollTo({ position: 'bottom', silent: true });
    });
  });

  function initLogTimer(interval: number) {
    logIntervalId = setInterval(async () => {
      if (formValue.rsnode === '1') {
        const logMsg = await getlog();
        log(logMsg);
        logData.value = logMsg.senders;
      } else if (formValue.rsnode === '2') {
        const logMsg = await getSenderLog();
        log(logMsg);
        logSenderData.value = logMsg.senders;
      }
    }, interval);
  }

  function clearTimer() {
    clearInterval(logIntervalId);
  }

  function openLogHandler() {
    clearTimer();
    initLogTimer(2000);
  }

  function closeLogHandler() {
    clearTimer();
  }

  function clearLogHandler() {
    logMsgList.value = [];
  }

  onMounted(async () => {
    // 初始化日志定时器
    clearTimer();
    initLogTimer(2000);

    const wireless = await getWireless();
    //console.log(wireless);
    Object.assign(formValue, wireless);
    parseLcghz(formValue.lcghz);
  });

  onUnmounted(() => {
    clearTimer();
  });

  watch(
    () => lcghzsValue.value,
    (newLcghzsValue) => {
      console.log(newLcghzsValue);
    }
  );

  function rowClassName(row: RowData) {
    return 'too-old';
  }
</script>
<style lang="less" scoped>
  .wireless-card-title {
    display: flex;
    justify-content: flex-start;
    align-items: center;

    .title-tag {
      margin-left: 20px;
    }
  }

  :deep(.too-old td) {
    background-color: white !important;
    //color: rgba(255, 0, 0, 0.75) !important;
    color: black !important;
  }
  :deep(.customTabbleClass) {
    background-color: #abbaca !important;
    color: aliceblue !important;
  }
</style>
